#include <SDL_error.h>
_Pragma("once")

#include "pch.hpp"
#include "log.hpp"
#include "libmath.hpp"

#define LogeWithSDLErr(msg) Loge(std::string(msg) + ";" + SDL_GetError())
#define LogeWithSDLImageErr(msg) Loge(std::string(msg) + ";" + IMG_GetError())
#define LogeWithSDLTTFErr(msg) Loge(std::string(msg) + ";" + TTF_GetError())

namespace sdl_engine {

////// NOTE: is this unsafe? return a temporary const char*

class SDLRuntimeError: public std::runtime_error {
public:
    SDLRuntimeError(const std::string& msg): std::runtime_error(msg) {}

    inline const char* what() const noexcept override {
        char* buf = new char[1024];
        std::snprintf(buf, sizeof(buf),
                      "%s; %s:%s\n",
                      std::runtime_error::what(),
                      "[SDL]", SDL_GetError());
        return buf;
    }
};

class SDLImageRuntimeError: public std::runtime_error {
public:
    SDLImageRuntimeError(const std::string& msg): std::runtime_error(msg) {}

    inline const char* what() const noexcept override {
        char* buf = new char[1024];
        std::snprintf(buf, sizeof(buf),
                      "%s; %s:%s\n",
                      std::runtime_error::what(),
                      "[SDL_image]", SDL_GetError());
        return buf;
    }
};

class SDLTTFRuntimeError: public std::runtime_error {
public:
    SDLTTFRuntimeError(const std::string& msg): std::runtime_error(msg) {}

    inline const char* what() const noexcept override {
        char* buf = new char[1024];
        std::snprintf(buf, sizeof(buf),
                      "%s; %s:%s\n",
                      std::runtime_error::what(),
                      "[SDL_ttf]", SDL_GetError());
        return buf;
    }
};

inline SDL_Rect Rect2SDL(const Rect& rect) {
    return {rect.position.x, rect.position.y, rect.size.w, rect.size.h};
}

inline SDL_Color Color2SDL(const Color& color) {
    return {color.r, color.g, color.b, color.a};
}

inline SDL_Point Point2SDL(const Point& point) {
    return {point.x, point.y};
}

}
